//---------------------------------------------------------------------------


#pragma hdrstop

#include "XTrayIcon.h"
/*#include <Classes.hpp>
#include <ComCtrls.hpp>
#include <Controls.hpp>
#include <ExtCtrls.hpp>
#include <StdCtrls.hpp>
*/
//---------------------------------------------------------------------------

#pragma package(smart_init)


__fastcall TXTrayIcon::TXTrayIcon()
{
    FVisible= false;
    Popup= NULL;
    FOnClose= NULL;
    FOnClick= NULL;
    FOnDldClick= NULL;
}

__fastcall TXTrayIcon::~TXTrayIcon()
{
    if(FVisible)
        Remove();
}

bool __fastcall TXTrayIcon::Add(HICON hIcon, char *tip)
{
    if(FVisible)
        return false;

    icon.cbSize= sizeof(icon);
    icon.hWnd= AllocateHWnd(WndProc);
    icon.uID= 0;
    icon.uFlags= NIF_ICON | NIF_MESSAGE | NIF_TIP;
    icon.uCallbackMessage= TRAY_CALLBACK;
    icon.hIcon= hIcon;

    icon.szTip[0]= 0;
    if(tip)
        if(strlen(tip) <= 63)
            strcpy(icon.szTip, tip);

    if(!Shell_NotifyIconA(NIM_ADD, &icon))
        return false;

    FVisible= true;

    return true;
}

bool __fastcall TXTrayIcon::Icon(HICON hIcon, char *tip)
{
    if(!FVisible)
        return false;

    if(hIcon)
        icon.hIcon= hIcon;

    icon.szTip[0]= 0;
    if(tip)
        if(strlen(tip) <= 63)
            strcpy(icon.szTip, tip);

// imagino que a mensagem sera sempre a mesma....
//    icon.uFlags= NIF_ICON | NIF_MESSAGE | NIF_TIP;
    icon.uFlags= NIF_ICON | NIF_TIP;

    if(!Shell_NotifyIconA(NIM_MODIFY, &icon))
        return false;

    return true;
}

bool __fastcall TXTrayIcon::Remove(void)
{
    if(!FVisible)
        return false;

// isso me faz mas sentido se usado depois de deletar o icone
//    DeallocateHWnd(icon.hWnd);

    if(!Shell_NotifyIconA(NIM_DELETE, &icon))
        return false;

    DeallocateHWnd(icon.hWnd);

    FVisible= false;

    return true;
}

bool __fastcall TXTrayIcon::Ballon(unsigned tipo, char *titulo,
                                                 char *texto, unsigned timeout)
{
    if(!FVisible)
        return false;

    icon.uFlags= NIF_INFO;
    strcpy(icon.szInfo, texto);
    icon.uTimeout= timeout;
    strcpy(icon.szInfoTitle, titulo);
    icon.dwInfoFlags= tipo;

    if(!Shell_NotifyIconA(NIM_MODIFY, &icon))
        return false;

    return true;
}


//!
void __fastcall TXTrayIcon::Minimize(void)
{
    Application->Minimize();
    ShowWindow(Application->Handle, SW_HIDE);
}


//!
void __fastcall TXTrayIcon::Restore(void)
{
    ShowWindow(Application->Handle, SW_SHOW);
    Application->Restore();
    Application->BringToFront();
}


//!
void __fastcall TXTrayIcon::WndProc(TMessage &Msg)
{
    TPoint pt;

    if(Msg.Msg == TRAY_CALLBACK)
    {
        Msg.Result= true; //pode ser alterado pelo default

        switch(Msg.LParam)
        {
            case WM_MOUSEMOVE:
            case WM_LBUTTONDOWN:
            case WM_LBUTTONUP:
                break;

            case WM_LBUTTONDBLCLK:
                if(FOnDldClick)
                    FOnDldClick(NULL);

            case WM_RBUTTONDOWN:
                break;

            case WM_RBUTTONUP:
                if(Popup)
                {
                    GetCursorPos(&pt);
                    Popup->Popup(pt.x, pt.y);
                }
                break;

            case WM_RBUTTONDBLCLK:
                break;

            case NIN_BALLOONSHOW: //quando o balao aparece
                break;

            case NIN_BALLOONHIDE: //quando o balao some que nao seja por
                                  //timeout ou por click do usuario
                Icon(NULL, NULL);
                if(FOnClose)
                    FOnClose(NULL);
                break;

            case NIN_BALLOONTIMEOUT: //quando some por timeout
                Icon(NULL, NULL);
                if(FOnClose)
                    FOnClose(NULL);
                break;

            case NIN_BALLOONUSERCLICK: //quando some por click
                Icon(NULL, NULL);
                if(FOnClick)
                    FOnClick(NULL);
                break;

            default:
                Msg.Result= DefWindowProc(icon.hWnd, Msg.Msg, Msg.WParam,
                                                                   Msg.LParam);
        }
    }
    else
        Msg.Result= DefWindowProc(icon.hWnd, Msg.Msg, Msg.WParam, Msg.LParam);
}
